package com.phery.minicap;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.Buffer;

public class MiniCap
{
	private RefreshListener listener;

	public MiniCap(RefreshListener listener)
	{
		this.listener = listener;
	}

	int readBannerBytes = 0;
	int bannerLength = 24;
	int readFrameBytes = 0;
	int frameBodyLength = 0;
	byte[] frameBody = new byte[0];
	String[] banner = new String[24];

	public void tryRead()
	{
		Socket socket;
		InputStream stream = null;
		try
		{
			socket = new Socket("127.0.0.1", 1717);
			stream = socket.getInputStream();
		} catch (UnknownHostException e1)
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1)
		{
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		while (true)
		{
			try
			{
				DataInputStream input = new DataInputStream(stream);
				int len = input.available();// 获取读到的字节长度
				byte[] chunk = new byte[len];
				input.read(chunk);// 将读取的字节保存到chunk
				// System.out.println("拉取到长度：" + len);
				for (int cursor = 0; cursor < len;)
				{
					if (readBannerBytes < bannerLength)
					{
						switch (readBannerBytes)
						{
						case 0:
							// version
							banner[0] = chunk[cursor] + "";
							System.out.println("Banner Version:" + banner[0]);
							break;
						case 1:
							// length
							bannerLength = chunk[cursor];
							banner[1] = String.valueOf(bannerLength);
							System.out.println("Banner bannerLength:" + banner[1]);
							break;
						// case 2:
						// case 3:
						// case 4:
						case 5:

							// byte[] temp = new byte[4];
							// System.arraycopy(chunk, 2, temp, 0, 4);
							banner[5] = bytesToLong(chunk, 2) + "";
							// pid
							// banner[5] += (chunk[cursor] << ((readBannerBytes
							// - 2) * 8)) >>> 0;
							System.out.println("Banner pid:" + banner[5]);
							break;
						// case 6:
						// case 7:
						// case 8:
						case 9:
							// real width
							banner[9] = bytesToLong(chunk, 6) + "";
							// banner[9] += (chunk[cursor] << ((readBannerBytes
							// - 6) * 8)) >>> 0;
							System.out.println("Banner real width:" + banner[9]);
							break;
						// case 10:
						// case 11:
						// case 12:
						case 13:
							// real height
							banner[13] = bytesToLong(chunk, 10) + "";
							// banner[13] += (chunk[cursor] << ((readBannerBytes
							// - 10) * 8)) >>> 0;
							System.out.println("Banner real height:" + banner[13]);
							break;
						// case 14:
						// case 15:
						// case 16:
						case 17:
							// virtual width
							banner[17] = bytesToLong(chunk, 14) + "";
							// banner[17] += (chunk[cursor] << ((readBannerBytes
							// - 14) * 8)) >>> 0;
							System.out.println("Banner virtual width:" + banner[17]);
							break;
						// case 18:
						// case 19:
						// case 20:
						case 21:
							// virtual height
							banner[21] = bytesToLong(chunk, 18) + "";
							// banner[21] += (chunk[cursor] << ((readBannerBytes
							// - 18) * 8)) >>> 0;
							System.out.println("Banner virtual height:" + banner[21]);
							break;
						case 22:
							// orientation
							banner[22] += chunk[cursor] * 90;
							System.out.println("Banner orientation:" + banner[22]);
							break;
						case 23:
							// quirks
							banner[23] = chunk[cursor] + "";
							System.out.println("Banner quirks:" + banner[23]);
							break;
						}

						cursor += 1;
						readBannerBytes += 1;

						if (readBannerBytes == bannerLength)
						{
							System.out.println("banner读取完毕！");
							// console.log('banner', banner)
						}
					} else if (readFrameBytes < 4)
					{

						frameBodyLength = (int) bytesToLong(chunk, 0);
						// System.out.println("获取字节长度：" + frameBodyLength);
						// frameBodyLength += (chunk[cursor] << (readFrameBytes
						// * 8)) >>> 0;
						if (frameBodyLength < 0 || frameBodyLength > 999999)
						{

							cursor += frameBodyLength;
							frameBodyLength = readFrameBytes = 0;
							frameBody = new byte[0];
							continue;
						}
						cursor += 4;
						readFrameBytes += 4;
					} else
					{
						if (len - cursor >= frameBodyLength)
						{
							// console.info('bodyfin(len=%d,cursor=%d)',
							// frameBodyLength, cursor)
							byte[] temp = new byte[cursor + frameBodyLength];
							System.arraycopy(chunk, cursor, temp, 0, cursor + frameBodyLength);
							frameBody = addBytes(frameBody, temp);

							// Sanity check for JPG header, only here for
							// debugging purposes.
							// System.out.println("frameBody[0]:" + frameBody[0]
							// + " frameBody[1]" + frameBody[1]
							// + " 0xFF:" + 0xFF + " 0xD8:" + 0xD8);
							// if (frameBody[0] != -1 || frameBody[1] != -40)
							// {

							// cursor += frameBodyLength;
							// frameBodyLength = readFrameBytes = 0;
							// frameBody = new byte[0];
							// console.error(
							// 'Frame body does not start with JPG header',
							// frameBody)
							// continue;
							// }
							// System.out.println("读取完毕：" + frameBody.length);
							listener.refresh(frameBody);

							cursor += frameBodyLength;
							frameBodyLength = readFrameBytes = 0;
							frameBody = new byte[0];
						} else
						{
							// console.info('body(len=%d)', len - cursor)

							byte[] temp = new byte[len - cursor];
							System.arraycopy(chunk, cursor, temp, 0, len - cursor);
							frameBody = addBytes(frameBody, temp);
							// System.out.println("body:" + (len - cursor));
							// System.out.println("frameBodyLength:" +
							// frameBodyLength);

							frameBodyLength -= len - cursor;
							readFrameBytes += len - cursor;
							cursor = len;
						}
					}
				}
			} catch (Exception e)
			{
				e.printStackTrace();
				System.out.println("报错了");
			}
		}
	}

	/**
	 * byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序，和和intToBytes（）配套使用
	 * 
	 * @param src
	 *            byte数组
	 * @param offset
	 *            从数组的第offset位开始
	 * @return int数值
	 */
	public static long bytesToLong(byte[] src, int offset)
	{
		long value;
		value = (long) ((src[offset] & 0xFF) | ((src[offset + 1] & 0xFF) << 8) | ((src[offset + 2] & 0xFF) << 16)
				| ((src[offset + 3] & 0xFF) << 24));
		return value;
	}

	/**
	 * 
	 * @param data1
	 * @param data2
	 * @return data1 与 data2拼接的结果
	 */
	public static byte[] addBytes(byte[] data1, byte[] data2)
	{
		byte[] data3 = new byte[data1.length + data2.length];
		System.arraycopy(data1, 0, data3, 0, data1.length);
		System.arraycopy(data2, 0, data3, data1.length, data2.length);
		return data3;

	}
}
